package com.shenda;

import java.util.Set;
import java.util.function.Consumer;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.shenda.device.Devices;
import com.shenda.device.codec.ChannelHeartbeat;
import com.shenda.device.codec.ChannelOperations;
import com.shenda.device.codec.CommandDecoder;
import com.shenda.device.codec.CommandEncoder;
import com.shenda.device.handler.Handlers;
import com.shenda.log.LogHandler;
import com.shenda.security.RolesxHandler;
import com.swak.config.vertx.SecurityConfigurationSupport;
import com.swak.rxtx.channel.Channel;
import com.swak.rxtx.channel.Channel.Property;
import com.swak.security.JWTAuthOptions;
import com.swak.security.options.KeyStoreOptions;
import com.swak.utils.Sets;
import com.swak.vertx.config.IRouterConfig;
import com.swak.vertx.config.VertxProperties;
import com.swak.vertx.protocol.http.StaticHandler;
import com.swak.vertx.security.SecurityHandler;
import com.swak.vertx.transport.VertxProxy;

import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;

/**
 * 项目配置
 * 
 * @author lifeng
 */
@Configuration
@SuppressWarnings("deprecation")
public class AppConfiguration {

	/**
	 * channel 初始化器
	 * 
	 * @return
	 */
	@Bean
	public Consumer<Channel> channelInit(Handlers handler) {
		return (channel) -> {
			channel.property(new Property().setReadSizeOnce(100));
			channel.pipeline().add(new CommandDecoder());
			channel.pipeline().add(new ChannelOperations().setHandler(handler));
			channel.pipeline().add(new ChannelHeartbeat());
			channel.pipeline().add(new CommandEncoder());
		};
	}

	/**
	 * 设备管理器(不要让spring来执行close方法)
	 * 
	 * @return
	 */
	@Bean(destroyMethod = "")
	public Devices devices() {
		return new Devices();
	}

	/**
	 * 安全过滤
	 * 
	 * @return
	 */
	@Bean
	public SecurityConfigurationSupport securitySupport() {

		// 认证授权配置（可以配置多种认证授权算法）
		JWTAuthOptions jwtAuthOptions = new JWTAuthOptions();
		jwtAuthOptions.setKeyStore(new KeyStoreOptions().setPath("keystore.jceks") // 查找classes根目录keystore.jceks文件
				.setPassword("secret"));

		// 权限配置
		SecurityConfigurationSupport support = new SecurityConfigurationSupport();
		support.addHandler("rolex", new RolesxHandler()) // 权限校验
				.definition("/=rolex") // 管理
				.setJwtAuthOptions(jwtAuthOptions);
		return support;
	}

	/**
	 * 网站自定义的路由配置， 可以配置多个
	 * 
	 * @return
	 */
	@Bean
	public IRouterConfig routerConfig(SecurityHandler securityHandler, VertxProperties properties) {
		return new IRouterConfig() {
			@Override
			public void apply(VertxProxy vertx, Router router) {
				Set<String> headers = Sets.newHashSet();
				headers.add("X-Requested-With");
				headers.add(properties.getJwtTokenName());
				router.route().handler(CorsHandler.create(".*").allowCredentials(true).allowedHeaders(headers)
						.maxAgeSeconds(30 * 24 * 60 * 60));
				router.route()
						.handler(BodyHandler.create(properties.getUploadDirectory())
								.setBodyLimit(properties.getBodyLimit())
								.setDeleteUploadedFilesOnEnd(properties.isDeleteUploadedFilesOnEnd()));
				router.route().handler(StaticHandler.create("static")); //
				router.route().handler(securityHandler);
				router.route().handler(new LogHandler());
			}
		};
	}
}